﻿#include "DraggableWidget.h"

#include <QMouseEvent>
#include <QSizePolicy>

DraggableWidget::DraggableWidget(QWidget *parent) : QWidget(parent)
  , m_bMovable(true)
  , m_bPressed(false)
  , m_pSourcePosition(QPoint())
  , m_bSizeFixed(false)
  , m_uValidBorderDistance(DEFAULT_VALID_BORDER_DISTANCE)
{
    setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
    setMouseTracking(true);
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}

DraggableWidget::~DraggableWidget()
{
}

void DraggableWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::RightButton)
    {
        m_bPressed = false;
        QWidget::mousePressEvent(event);
        return;
    }
    m_bPressed = true;
    m_pSourcePosition = event->globalPos();
    QWidget::mousePressEvent(event);
}

void DraggableWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (isMaximized() || (windowState() == Qt::WindowFullScreen))
    {
        QWidget::mouseMoveEvent(event);
        return;
    }
    QPoint pt = event->pos();
    if (!m_pSourcePosition.isNull())
    {
        pt = mapFromGlobal(m_pSourcePosition);
    }
    bool bResize = true;
    QRect dialogGeometry = geometry();
    int dx = event->globalX() - m_pSourcePosition.x();
    int dy = event->globalY() - m_pSourcePosition.y();
    if (!m_bSizeFixed)
    {
        //TopLeft
        if (pt.x() <= m_uValidBorderDistance && pt.y() <= m_uValidBorderDistance)
        {
            setCursor(Qt::SizeFDiagCursor);
            dialogGeometry.setLeft(dialogGeometry.left() + dx);
            dialogGeometry.setTop(dialogGeometry.top() + dy);
        }
        //TopRight
        else if ((rect().right()-pt.x()) <= m_uValidBorderDistance && pt.y() <= m_uValidBorderDistance)
        {
            setCursor(Qt::SizeBDiagCursor);
            dialogGeometry.setRight(dialogGeometry.right() + dx);
            dialogGeometry.setTop(dialogGeometry.top() + dy);
        }
        //BottomRight
        else if ((rect().right()-pt.x()) <= m_uValidBorderDistance && (rect().bottom() - pt.y()) <= m_uValidBorderDistance)
        {
            setCursor(Qt::SizeFDiagCursor);
            dialogGeometry.setRight(dialogGeometry.right() + dx);
            dialogGeometry.setBottom(dialogGeometry.bottom() + dy);
        }
        //BottomLeft
        else if (pt.x() <= m_uValidBorderDistance && (rect().bottom() - pt.y()) <= m_uValidBorderDistance)
        {
            setCursor(Qt::SizeBDiagCursor);
            dialogGeometry.setLeft(dialogGeometry.left() + dx);
            dialogGeometry.setBottom(dialogGeometry.bottom() + dy);
        }
        //Left
        else if (pt.x() <= m_uValidBorderDistance)
        {
            setCursor(Qt::SizeHorCursor);
            dialogGeometry.setLeft(dialogGeometry.left() + dx);
        }
        //Top
        else if (pt.y() <= m_uValidBorderDistance)
        {
            setCursor(Qt::SizeVerCursor);
            dialogGeometry.setTop(dialogGeometry.top() + dy);
        }
        //Right
        else if ((rect().right() - pt.x()) <= m_uValidBorderDistance)
        {
            setCursor(Qt::SizeHorCursor);
            dialogGeometry.setRight(dialogGeometry.right() + dx);
        }
        //Bottom
        else if ((rect().bottom() - pt.y()) <= m_uValidBorderDistance)
        {
            setCursor(Qt::SizeVerCursor);
            dialogGeometry.setBottom(dialogGeometry.bottom() + dy);
        }
        else
        {
            setCursor(Qt::ArrowCursor);
            bResize = false;
        }
    }
    else
    {
        setCursor(Qt::ArrowCursor);
        bResize = false;
    }
    if (m_bPressed)
    {
        if (bResize) //伸缩窗口
        {
            if (!m_pSourcePosition.isNull() && !m_bSizeFixed)
            {
                setGeometry(dialogGeometry);
            }
        }
        else
        {
            if (!m_pSourcePosition.isNull() && m_bMovable) //移动窗口
            {
                move(pos() + (event->globalPos() - m_pSourcePosition));
            }
        }
        m_pSourcePosition = event->globalPos();
    }
    QWidget::mouseMoveEvent(event);
}

void DraggableWidget::mouseReleaseEvent(QMouseEvent *event)
{
    m_bPressed = false;
    m_pSourcePosition = QPoint();
    QWidget::mouseReleaseEvent(event);
}

void DraggableWidget::setWindowMovable(bool m_movable)
{
    m_bMovable = m_movable;
}

bool DraggableWidget::windowMovable() const
{
    return m_bMovable;
}

void DraggableWidget::setWindowSizeFixed(bool m_fixed)
{
    m_bSizeFixed = m_fixed;
}

bool DraggableWidget::windowSizeFixed() const
{
    return m_bSizeFixed;
}

bool DraggableWidget::windowPressed() const
{
    return m_bPressed;
}

void DraggableWidget::setWindowValidBorderDistance(int m_distance)
{
    m_uValidBorderDistance = ((m_distance >= 1) && (m_distance <= 50)) ? m_distance : 5;
}

int DraggableWidget::validBorderDistance() const
{
    return m_uValidBorderDistance;
}
